/**
 ****************************************************************************************************
 * @file    main.c
 * @author  FMSH Application Team
 * @brief   Header file of FL Module
 ****************************************************************************************************
 * @attention
 *
 * Copyright (c) [2021] [Fudan Microelectronics]
 * THIS SOFTWARE is licensed under Mulan PSL v2.
 * can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 *
 ****************************************************************************************************
 */

#include "main.h"
#include "fm33_assert.h"
#include "log.h"
#include "BMI160.h"
#include "AT24C02.h"
#include "AHT20.h"
#include "MLCD.h"
#include "KEY.h"
#include "AXP2101.h"
#include "PCF85063.h"

// #include "flash.h"

const static char *TAG = "main.c";

static aht20_data aht20_panel;
static bmi160_acc_t bmi160_panel;

float easeInOut(float t, float b, float c, float d)
{
  t /= d / 2; // 归一化时间
  if (t < 1)
  {
    return c / 2 * t * t + b; // 缓入阶段
  }
  t--;
  return -c / 2 * (t * (t - 2) - 1) + b; // 缓出阶段
}

void animal_demo(void)
{
  float startValue = 0;  // 起始值
  float endValue = 100;  // 目标值
  float duration = 1.0;  // 动画持续时间（秒）
  float timeStep = 0.1;  // 时间步长（模拟帧率）
  float currentTime = 0; // 当前时间
  float value;
  MY_LOGI(TAG, "Time\tValue\n");
  while (currentTime <= duration)
  {
    // 使用缓动函数计算当前值
    value = easeInOut(currentTime, startValue, endValue - startValue, duration);
    // 输出时间和属性值
    MY_LOGI(TAG, "%.1f\t%.2f\n", currentTime, value);
    // 增加时间
    currentTime += timeStep;
  }
}
const uint8_t is_charging[] = "is charging";
const uint8_t on_charging[] = "no charging";

int main(void)
{
  /* Initialize FL Driver Library */
  FL_Init();

  /* Configure the system clock */
  MF_Clock_Init();

  /* Initialize all configured peripherals */
  MF_Config_Init();
  mf_uart0_init(115200);                                                               /* init uart0 */
  mf_uart_dma_init();                                                                  /* init uart0_dma */
  mf_spi_init();                                                                       /* init spi */
  mf_i2c_master_init(MF_I2C_BASE, GPIOC, FL_GPIO_PIN_5, GPIOC, FL_GPIO_PIN_4, 400000); /* init i2c */
  mf_bstim_init(3, 640000);                                                            /* Tout = (3)*(640000) / 64MHz = 0.030s */
  mf_gptim_init(8000, 8000);															   /* Tout = (8000)*(8000) / 64MHz = 1s */

  /* init device */
  FL_DelayMs(10); /* wait 10ms */
  key_gpio_init();
  axp2101_init();
  bmi160_init();
  at24_demo();
  aht20_init();

  /* init user devices */
  mlcd_init();                     /* init mlcd */
  FL_DelayMs(10);                  /* wait 10ms */
  mf_bstim_enable(FL_ENABLE);      /* enable bstim */
  mf_iwdt_init(MF_IWDT_TIM_500MS); /* init iwdt */
  MY_LOGI(TAG, "FM33LE023. Are you ok?\r\n");

  uint8_t rand_x = 'a', rand_y, rand_color = '0';
  uint8_t str_buff[18] = "BatLevel:100%";
  bool charging_flag;

  while (1)
  {
    key_scan_proc(); /* scan key */
    FL_DelayMs(5);   /* wait 5ms */

    if (bstim_get_data()->iwdt_time_count >= 1)
    {
      mlcd_memset_buff();
      drawBox(70, rand_y++, 20, 20, BLACK);
      drawBox(10, rand_y++, 20, 20, YELLOW);
      drawBox(100, 128 - (rand_y++), 20, 20, GREEN);
      drawFrame(50 - 5, 50 - 5, 20, 20, BLACK);
      mlcd_WriteChar(rand_x++, 50, 50, Font_7x10, RED);
      drawFrame(50 - 5, 80 - 5, 20, 20, BLACK);
      mlcd_WriteChar(rand_color++, 50, 80, Font_7x10, BLUE);
      if (rand_x > 'z')
      {
        rand_x = 'a';
      }
      if (rand_color > '9')
      {
        rand_color = '0';
      }
      if (rand_y > 128)
      {
        rand_y = 0;
      }
      bstim_get_data()->iwdt_time_count = 0;

      mlcd_WriteString(str_buff, 0, 2, Font_7x10, RED);
      charging_flag ? mlcd_WriteString(is_charging, 0, 12, Font_7x10, RED) : mlcd_WriteString(on_charging, 1, 12, Font_7x10, RED);
      mlcd_semaphore_frame(); /* set mlcd_refresh semaphore */
    }

    if (key_msg_point()->pressed)
    {
      key_msg_point()->pressed = false;
      switch (key_msg_point()->id)
      {
      case 0:
        MY_LOGI(TAG, "KEY[%d] Pressed\r\n", key_msg_point()->id);
        break;
      case 1:
        MY_LOGI(TAG, "KEY[%d] Pressed\r\n", key_msg_point()->id);
        axp2101_pwr_off();
        break;
      case 2:
        animal_demo();
        MY_LOGI(TAG, "KEY[%d] Pressed\r\n", key_msg_point()->id);
        break;
      }
    }

    /* sensor scan start */
    if (bstim_get_data()->time_count >= 100)
    {
      MY_LOGI(TAG, "BSTIM -> %ds.\r\n", bstim_get_data()->time_count / 100);
      bstim_get_data()->time_count = 0;

      sprintf(str_buff, "BatLevel:%d%%", axp2101_bat_level());
      axp2101_is_charging() ? (charging_flag = 1) : (charging_flag = 0);
      aht20_read_from_device(&aht20_panel);
      bmi160_get_acc(&bmi160_panel);
      pcf85063_read_data();
    }
    /* sensor scan end */
  }
}
